<?php
// +----------------------------------------------------------------------
// | Created by [ PhpStorm ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 上海到啦网络科技有限公司.
// +----------------------------------------------------------------------
// | Create Time ( 2017/8/24 0024 - 下午 4:52)
// +----------------------------------------------------------------------
// | Author: tangyijun <251784425@qq.com>
// +----------------------------------------------------------------------
namespace app\extra;
use think\Config;
use think\Db;

class Generate{
    //控制器黑名单设置
    const BLACK_CONTROLLER = [
        'rule',
        'admin',
        'role',
        'config',
        'system',
        'base',
        'index',
        'logon',
        'code',
        'universal'
    ];
    //数据表黑名单设置
    const BLACK_TABLE_NAME = [
        'admin',
        'auth_group',
        'auth_group_access',
        'auth_rule',
        'config'
    ];

    /**
     * @param $path
     * @return array|bool
     * 检查目录
     */
    public static function checkAuthority($path){
        if(file_exists($path)){
            return true;
        }else{
            return ['errorMsg'=>'该文件夹不存在'];
        }
        if(is_writable($path)){
            return true;
        }else{
            return ['errorMsg'=>'文件夹没有可写权限'];
        }
    }

    /**
     * @return bool
     * 自动生成文件入口文件
     */
    public static function run(){
        $post = request()->post();
        $res = self::createController($post);
        //创建数据表
        if($res){
            $res = self::createSqlTable($post);
        }
        //创建模型
        if($res){
            if(1 == $post['is_create_model']){
                $res = self::createModel($post['controller_name'],$post['table_name']);
            }
        }
        //创建检索条件
        if($res){
            $res = self::createSearch($post);
        }
        if($res){
            $url = url('code/form',$post);
            return $url;
        }else{
            return false;
        }
    }

    /**
     * @param $post
     * @return bool
     */
    private static function createController($post){
        showMsg('正在检测目录权限等');
        $path = $path = APP_PATH.'admin'.DS.'controller';
        $res = self::checkAuthority($path);
        if(!$res){
            showMsg($res['errorMsg']);
            return false;
        }
        //检查控制器名称是否在黑名单内
        foreach(self::BLACK_CONTROLLER as $v){
            if($v === $post['controller_name']){
                showMsg('该控制器禁止被创建，请重新设置名称');
                return false;
            }
        }
        //检查表明是否在黑名单内
        foreach(self::BLACK_TABLE_NAME as $v){
            if($v === $post['table_name']){
                showMsg('该表名禁止被创建，请重新设置名称');
                return false;
            }
        }
        //配置检索条件
        switch ($post){
            case !empty($post['title']) && empty($post['create_time']):
                $post['search'] = "['title'=>'like']";
                break;
            case !empty($post['create_time']) && empty($post['title']):
                $post['search'] = "['create_time' => 'time']";
                break;
            case !empty($post['title'] && !empty($post['create_time'])):
                $post['search'] = "['title'=>'like','create_time' => 'time']";
                break;
            default:
                $post['search'] = "[]";
        }
        //读取控制器模板
        $controller_path = APP_PATH.'temp/controller.tpl';
        $controller_temp = file_get_contents($controller_path);
        //替换控制器名
        foreach ($post as $name => $value) {
            $controller_temp = str_replace("-{$name}-", $value, $controller_temp);
        }
        //创建的文件名
        $path_file = $path.DS.$post['controller_name'].'.php';
        //写入文件
        $res = file_put_contents($path_file,$controller_temp);
        if($res){
            showMsg('创建控制器文件完成');
        }else{
            showMsg('该表名禁止被创建，请重新设置名称');
            return false;
        }
        return true;
    }

    /**
     * @param $post
     * @return bool
     * 创建数据表
     */
    private static function createSqlTable($post){
        showMsg('正在检查数据表');
        $table_name = Config::get('database.prefix').$post['table_name'];
        $sql = "SHOW TABLES LIKE '%{$table_name}%'";
        $res = Sql::_execute($sql);
        if(!empty($res)){
            showMsg('该表已经存在了，我们将强制删除新建的控制器文件，请重新设置...');
            $path_file = APP_PATH.'admin'.DS.'controller'.DS.$post['controller_name'].'.php';
            if(!unlink($path_file)){
                showMsg('文件删除失败，请重新删除');
                return false;
            }else{
                $url = 'http://'.$_SERVER['HTTP_HOST'].'/admin/code/codeTool';
                showMsg('<a href="'.$url.'">文件已经删除，点击返回！</a>');
                exit;
            }
        }
        showMsg('正在为您创建数据表');
        //根据条件自动创建一个含有主键的数据表
        switch ($post){
            case !empty($post['title']) && empty($post['create_time']):
                $sql = "CREATE TABLE `{$table_name}` (
                `id` int(11) NOT NULL AUTO_INCREMENT,PRIMARY KEY (`id`),
                `title` char(100) NOT NULL DEFAULT '' COMMENT '标题'
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ";
                break;
            case !empty($post['create_time']) && empty($post['title']):
                $sql = "CREATE TABLE `{$table_name}` (
                `id` int(11) NOT NULL AUTO_INCREMENT,PRIMARY KEY (`id`),
                `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间'
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ";
                break;
            case !empty($post['title'] && !empty($post['create_time'])):
                $sql = "CREATE TABLE `{$table_name}` (
                `id` int(11) NOT NULL AUTO_INCREMENT,PRIMARY KEY (`id`),
                `title` char(100) NOT NULL DEFAULT '' COMMENT '标题',
                `create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间'
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ";
                break;
            default:
                $sql = "CREATE TABLE `{$table_name}` (
                `id` int(11) NOT NULL AUTO_INCREMENT,PRIMARY KEY (`id`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ";
        }
        $res = Sql::_execute($sql);
        if($res === false){
            showMsg('遗憾创建数据表失败了');
            return false;
        }else{
            showMsg('恭喜，创建数据库文件已经完成');
            return true;
        }

    }

    /**
     * @param $controller_name
     * @param $table_name
     * @return bool
     * 创建模型
     */
    private static function createModel($controller_name,$table_name){
        showMsg('正在为您创建模型文件');
        $path = $path = APP_PATH.'model';
        $data['controller_name'] = $controller_name;
        $data['table_name'] = $table_name;
        //读取模型模板
        $model_path = APP_PATH.'temp/model.tpl';
        $model_temp = file_get_contents($model_path);
        //替换内容
        foreach ($data as $name => $value) {
            $model_temp = str_replace("-{$name}-", $value, $model_temp);
        }
        //创建的文件名
        $path_file = $path.DS.$controller_name.'.php';
        //写入文件
        $res = file_put_contents($path_file,$model_temp);
        if($res){
            showMsg('恭喜，创建模型文件已经完成');
            return true;
        }else{
            showMsg('抱歉，创建模型失败');
            return false;
        }
    }

    /**
     * @param $post
     * @return bool
     * 创建检索文件
     */
    private static function createSearch($post){
        if(!empty($post['title']) && empty($post['create_time'])){
            $data['search_html'] = "<input type=\"text\" value=\"<?php echo \$search['title']?>\"  class=\"input-text\" style=\"width:250px\" placeholder=\"输入关键字\" id=\"\" name=\"title\">\n";
        }elseif(!empty($post['create_time']) && empty($post['title'])){
            $data['search_html'] = "\<input type=\"text\" name=\"start_time\" onfocus=\"WdatePicker({ maxDate:'#F { $dp.$D(\'datemax\')||\'%y-%M-%d\' }' })\" value=\"<?php echo \$start_time?>\" id=\"datemin\" class=\"input-text Wdate\" style=\"width:120px;\">-
                                    <input type=\"text\" name=\"end_time\" onfocus=\"WdatePicker({ maxDate:'#F { \$dp.$D(\'datemin\') }',maxDate:'%y-%M-%d' })\" id=\"datemax\" value=\"<?php echo \$end_time?>\" class=\"input-text Wdate\" style=\"width:120px;\">\n";
        }elseif (!empty($post['title']) && !empty($post['create_time'])){
            $data['search_html'] = "<input type=\"text\" name=\"start_time\" onfocus=\"WdatePicker({ maxDate:'#F { $dp.$D(\'datemax\')||\'%y-%M-%d\' }' })\" value=\"<?php echo \$start_time?>\" id=\"datemin\" class=\"input-text Wdate\" style=\"width:120px;\">-
                                    <input type=\"text\" name=\"end_time\" onfocus=\"WdatePicker({ maxDate:'#F { \$dp.$D(\'datemin\') }',maxDate:'%y-%M-%d' })\" id=\"datemax\" value=\"<?php echo \$end_time?>\" class=\"input-text Wdate\" style=\"width:120px;\">\n";
        }else{
            $data['search_html'] = [''];
        }
        $path = APP_PATH.'admin'.DS.'view'.DS.strtolower($post['controller_name']);
        if (!file_exists($path)){
            mkdir ($path);
            showMsg('创建文件夹'.$post['controller_name'].'成功');
        } else {
            showMsg('创建文件夹失败');
            return false;
        }
        //读取搜索配置
        $search_path = APP_PATH.'temp/search.tpl';
        $search_temp = file_get_contents($search_path);
        //替换内容
        foreach ($data as $name => $value) {
            $controller_temp = str_replace("-{$name}-", $value, $search_temp);
        }
        //创建的文件名
        $path_file = $path.DS.'search.html';
        //写入文件
        $res = file_put_contents($path_file,$controller_temp);
        if($res){
            showMsg('创建搜索文件已经完成');
            return true;
        }else{
            showMsg('创建搜索文件失败');
            return false;
        }

    }

    /**
     * @return array|bool
     * 添加字段
     */
    public static function createField(){
        $post = request()->post();
        //检查该字段是否存在
        $sql = "desc {$post['table_name']}";
        $file_desc = Sql::_query($sql);
        foreach($file_desc as $v){
            if($v['Field'] == $post['field_name']){
                return ['errorMsg'=>'该字段已经存在了，请重新设置！'];
            }
        }
        $fields = self::getFieldMake($post['dtype'],$post['field_name'],$post['vdefault']);
        //添加一个字段
        $sql = "alter table `{$post['table_name']}` add {$fields[0]}";
        Db::startTrans();
        $res1 = Sql::_execute($sql);
        $res2 = self::getFieldMakeForm($post['dtype'],$post['field_name'],$post['field_comment'],$post['vdefault']);
        $data['table_name'] = $post['table_name'];
        $data['table_form_html'] = $res2;
        $res3 = Sql::_save('form_html',$data);
        if($res1!==false && $res3){
            Db::commit();
            return true;
        }else{
            Db::rollback();
            return ['errorMsg' => '数据库操作失败'];
        }
    }

    /**
     * @return array|bool
     * 创建添加和修改视图
     */
    public static function createCuView(){
        $post = request()->post();
        $path = APP_PATH.'temp'.DS.'cu.tpl';
        $html = file_get_contents($path);
        //替换内容
        $html =  str_replace("-form_html-", $post['form_html'], $html);
        //写入文件
        $path = APP_PATH.'admin'.DS.'view'.DS.strtolower($post['controller_name']).DS.'cu.html';
        //写入文件
        $res = file_put_contents($path,$html);
        if($res){
            return true;
        }else{
            return ['errorMsg' => '创建添加、修改器视图失败'];
        }
    }

    /**
     * @return array|bool
     * 创建列表视图
     */
    public static function createListView(){
        $post = request()->post();
        //创建表头
        $data ['list_head'] = '';
        foreach($post['list'] as $key => $value){
            if($value == 'on'){
                $data ['list_head'] .= '<th>'.$key.'</th>'."\n";
            }
        }
        //创建显示字段
        $data['list_td'] = '';
        foreach($post['list'] as $key => $value){
            if($value == 'on'){
                $data['list_td'] .= '<td>{$v.'.$key.'}</td>'."\n";
            }
        }
        $data['list_button'] = '';
        if($post['is_edit'] == 'on'){
            $data['list_button'] .= '<a title="编辑" href="javascript:;" onclick="rule_edit(\'编辑\',\'<?php echo url(\''.$post['controller_name'].'/cu\',[\'id\'=>$v[\'id\']])?>\',\'1\',\'\',\'510\')" class="ml-5" style="text-decoration:none"><i class="Hui-iconfont">&#xe6df;</i></a>'."\n";
        }
        if($post['is_del'] == 'on'){
            $data['list_button'] .= '<a title="删除" href="javascript:;" onclick="del('.$post['table_name'].',<?php echo $v[\'id\']?>)" class="ml-5" style="text-decoration:none"><i class="Hui-iconfont">&#xe6e2;</i></a>'."\n";
        }
        $data['more_del_head'] = '';
        $data['more_del_button'] = '';
        if($post['more_del'] == 'on'){
            $data['more_del_button'] = '<span class="l"><a href="javascript:;" onclick="datadel(\''.$post['controller_name'].'\')" class="btn btn-danger radius"><i class="Hui-iconfont"></i> 批量删除</a></span>';
            $data['more_del_head'] = '<th width="25" class="sorting_disabled" rowspan="1" colspan="1" aria-label="" style="width: 25px;"><input type="checkbox"  value=""></th>';
            $data['list_more_del'] = '<td><input name="ids"  type="checkbox" value="<?php echo $v[\'id\']?>"></td>';
        }
        $data['list_action'] = $post['controller_name'];
        //读取列表模板
        $temp_path = APP_PATH.'temp/list.tpl';
        //读取模板内容
        $list_temp = file_get_contents($temp_path);
        //替换内容
        foreach ($data as $name => $value) {
            $list_temp = str_replace("-{$name}-", $value, $list_temp);
        }
        //创建的文件名
        $path_file = APP_PATH.'admin'.DS.'view'.DS.strtolower($post['controller_name']).DS.$post['controller_name'].'List.html';
        //写入文件
        $res = file_put_contents($path_file,$list_temp);
        if($res){
            return true;
        }else{
            return ['errorMsg' => '创建列表页视图失败'];
        }

    }

    /**
     * @param $dtype
     * @param $field_name
     * @param $field_comment
     * @param $dfvalue
     * @return string
     */
    private static function getFieldMakeForm($dtype ,$field_name,$field_comment,$dfvalue){
        $path = APP_PATH.'temp'.DS;
        if($dtype == 'int' || $dtype == 'text' || $dtype == 'textchar' || $dtype == 'float' || $dtype == 'imgfile'){
            //普通文本域
            $path = $path.'input.tpl';
            $temp = file_get_contents($path);
        } elseif($dtype == 'multitext'){
            //普通的areatext
            $path = $path.'areatext.tpl';
            $temp = file_get_contents($path);
        } elseif($dtype == 'htmltext' || $dtype == 'textdata'){
            //富文本编辑器
            $path = $path.'edit.tpl';
            $temp = file_get_contents($path);
        }elseif($dtype == 'img'){
            //图片上传
            $path = $path.'image.tpl';
            $temp = file_get_contents($path);
        }
        if($dtype == 'select'){
            //生成下拉菜单
            $path = $path.'select.tpl';
            $temp = file_get_contents($path);
            $default_value = explode(',',$dfvalue);
            $option = '';
            foreach ($default_value as $name){
                $option .= '<option value="'.$name.'">'.$name.'</option>'."\n";
            }
            //替换内容
            $temp =  str_replace("-option-", $option, $temp);
        }
        if($dtype == 'radio'){
            //生成单选框
            $path = $path.'audio.tpl';
            $temp = file_get_contents($path);
            $default_value = explode(',',$dfvalue);
            $radio = '';
            foreach ($default_value as $name){
                $radio .= '<div class="radio-box"><input type="radio" name="'.$field_name.'"><label for="model_id-2">'.$name.'</label></div>';
            }
            $temp =  str_replace("-radio-", $radio, $temp);
        }
        //替换字段
        $temp =  str_replace("-field_comment-", $field_comment, $temp);
        //替换字段
        $temp =  str_replace("-field_name-", $field_name, $temp);
        return $temp;
    }
    /**
     * @param $dtype
     * @param $fieldname
     * @param $dfvalue
     * @param $mxlen
     * @return array
     * 生成返回sql
     */
    private static  function getFieldMake($dtype, $fieldname, $dfvalue, $mxlen = '255'){
        $fields = [];
        if($dtype == "int" || $dtype == "datetime")
        {
            if($dfvalue == "" || preg_match("#[^0-9-]#", $dfvalue))
            {
                $dfvalue = 0;
            }
            $fields[0] = " `$fieldname` int(11) NOT NULL default '$dfvalue';";
            $fields[1] = "int(11)";
        }
        else if($dtype == "stepselect")
        {
            if($dfvalue == "" || preg_match("#[^0-9\.-]#", $dfvalue))
            {
                $dfvalue = 0;
            }
            $fields[0] = " `$fieldname` char(20) NOT NULL default '$dfvalue';";
            $fields[1] = "char(20)";
        }
        else if($dtype == "float")
        {
            if($dfvalue == "" || preg_match("#[^0-9\.-]#", $dfvalue))
            {
                $dfvalue = 0;
            }
            $fields[0] = " `$fieldname` float NOT NULL default '$dfvalue';";
            $fields[1] = "float";
        }
        else if($dtype == "img" || $dtype == "media" || $dtype == "addon" || $dtype == "imgfile")
        {
            if(empty($dfvalue)) $dfvalue = '';
            if($mxlen=="") $mxlen = 200;
            if($mxlen > 255) $mxlen = 100;

            $fields[0] = " `file_path` varchar($mxlen) NOT NULL default '$dfvalue';";
            $fields[1] = "varchar($mxlen)";
        }
        else if($dtype == "multitext" || $dtype == "htmltext")
        {
            $fields[0] = " `$fieldname` mediumtext;";
            $fields[1] = "mediumtext";
        }
        else if($dtype=="textdata")
        {
            if(empty($dfvalue)) $dfvalue = '';

            $fields[0] = " `$fieldname` varchar(100) NOT NULL default '';";
            $fields[1] = "varchar(100)";
        }
        else if($dtype=="textchar")
        {
            if(empty($dfvalue)) $dfvalue = '';

            $fields[0] = " `$fieldname` char(100) NOT NULL default '$dfvalue';";
            $fields[1] = "char(100)";
        }
        else if($dtype=="checkbox")
        {
            $dfvalue = str_replace(',',"','",$dfvalue);
            $dfvalue = "'".$dfvalue."'";
            $fields[0] = " `$fieldname` SET($dfvalue) NULL;";
            $fields[1] = "SET($dfvalue)";
        }
        else if($dtype=="select" || $dtype=="radio")
        {
            $dfvalue = str_replace(',', "','", $dfvalue);
            $dfvalue = "'".$dfvalue."'";
            $fields[0] = " `$fieldname` enum($dfvalue) NULL;";
            $fields[1] = "enum($dfvalue)";
        }
        else
        {
            if(empty($dfvalue))
            {
                $dfvalue = '';
            }
            if(empty($mxlen))
            {
                $mxlen = 100;
            }
            if($mxlen > 255)
            {
                $mxlen = 250;
            }
            $fields[0] = " `$fieldname` varchar($mxlen) NOT NULL default '$dfvalue';";
            $fields[1] = "varchar($mxlen)";
        }
        return $fields;
    }

}